package main

import (
	"fmt"
)

const ()

func main() {
	// a := transform(13, 4)
	// fmt.Println(function(a))

	var N int //输出数量
	var n int //变量数量
	var wx int
	var bf int
	N = 2
	n = 2

	walsh := make([][]int, exponent(2, N)) //Walsh谱矩阵
	for i := 0; i < exponent(2, N); i++ {
		walsh[i] = make([]int, exponent(2, n))
	}

	for i := 0; i < exponent(2, N); i++ { //b
		for j := 0; j < exponent(2, n); j++ { //w
			for k := 0; k < exponent(2, n); k++ { //x
				x := transform(k, n)
				w := transform(j, n)
				b := transform(i, N)
				wx = multiab(w, x)              //wx
				bf = multiab(b, function(x, n)) //bf(x)
				// fmt.Println(x, w, b, wx, bf)
				if (wx^bf)%2 == 1 { //wx+bf(x)
					walsh[i][j]--
				} else {
					walsh[i][j]++
				}
				// fmt.Println(x, w, b)
			}
			walsh[i][j] = walsh[i][j]
		}
	}

	display(walsh)
}

func f0(x []int, n int) int {
	return x[n-1] & x[n-2]
}
func f1(x []int, n int) int {
	return x[n-1] ^ x[n-2] //x1+x2
}
func f2(x []int, n int) int {
	return x[n-1] & x[n-2] //x1x2
}
func f3(x []int, n int) int {
	return x[n-3] ^ x[n-4] //x3+x4
}
func f4(x []int, n int) int {
	return x[n-3] & x[n-4] //x3x4
}
func f5(x []int, n int) int {
	return x[n-5] ^ x[n-6] //x5+x6
}
func f6(x []int, n int) int {
	return x[n-5] & x[n-6] //x5x6
}

func function(x []int, n int) (y []int) {
	// y = append(y, f6(x, n))
	// y = append(y, f5(x, n))
	// y = append(y, f4(x, n))
	// y = append(y, f3(x, n))
	y = append(y, f2(x, n))
	y = append(y, f1(x, n))
	// y = append(y, f0(x, n))
	return
}

func multiab(a []int, b []int) (c int) {
	for k, v := range a {
		c = c + v&b[k]
	}
	return c % 2
}

func transform(a int, n int) (b []int) {
	var flag int
	flag = 1
	b = make([]int, n)
	if a == 0 {
		return
	}
	for {
		if flag <= a {
			if (flag & a) != 0 {
				b[n-1] = 1
			}
			flag = flag << 1
			n--
		} else {
			return
		}
	}
}

func display(w [][]int) {
	for _, v := range w {
		for _, k := range v {
			fmt.Print("\t", k)
		}
		fmt.Print("\n")
	}
}

// func count(a int) int { //将按位与（即点乘）的结果转成0、1
// 	var c int
// 	var flag int
// 	flag = 1
// 	if a == 0 {
// 		return 0
// 	}
// 	for {
// 		if flag <= a {
// 			if (flag & a) != 0 {
// 				c++
// 			}
// 			flag = flag << 1
// 			fmt.Println(flag, c)
// 		} else {
// 			return flag % 2
// 		}
// 	}
// }

func exponent(a, n int) int {
	result := 1
	for i := n; i > 0; i >>= 1 {
		if i&1 != 0 {
			result *= a
		}
		a *= a
	}
	return result
}
